package cn.mrcode.wxsdk.core;

import cn.mrcode.wxsdk.core.context.ConfigContext;
import cn.mrcode.wxsdk.core.context.ParseConfig;
import cn.mrcode.wxsdk.core.context.SdkContexts;
import cn.mrcode.wxsdk.core.dialogue.common.PublicAccount;
import cn.mrcode.wxsdk.core.dialogue.common.accessToken.lifeCycle.IAccessTokenService;
import cn.mrcode.wxsdk.core.dialogue.common.accessToken.lifeCycle.distributed.AccessTokenDistributedService;
import cn.mrcode.wxsdk.core.dialogue.common.accessToken.lifeCycle.single.AccessTokenSingleService;
import cn.mrcode.wxsdk.core.dialogue.common.httpClient.DefeatHttpClient;
import cn.mrcode.wxsdk.core.dialogue.common.httpClient.IHttpClinet;
import cn.mrcode.wxsdk.core.dialogue.common.util.ClassUtil;
import cn.mrcode.wxsdk.core.dialogue.service.BaseService;
import cn.mrcode.wxsdk.core.dialogue.service.CommonService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;

/**
 * 新的初始化类
 *
 * @author zhuqiang
 * @version V1.0
 * @date 2016/6/15 16:59
 */
public class CoreInit implements Init {
    private static Logger log = LoggerFactory.getLogger(CoreInit.class);
    private ConfigContext configContext; //配置上下文环境

    private boolean initReady = false; //是否初始化完毕

    public CoreInit() {
        this(null,null);
    }

    /**
     * @param configName 配置文件名称，可为null；默认为sdk中的配置文件
     * @param id 每个应用的唯一id，用来分辨是谁在使用本sdk;可为null，默认为本机ip
     */
    public CoreInit(String configName,String id) {
        builder(configName,id);
    }

    private void builder(String configName,String id) {
        try {
            ConfigContext configContext = new ParseConfig(configName).parse();
            configContext.setId(id);
            SdkContexts.setConfigContext(configContext);
            this.configContext = configContext;
            init(configContext);
            initReady = true;
        } catch (Exception e) {
            log.error("微信sdk初始化出错，请仔细查看日志信息");
            throw new RuntimeException(e);
        }
    }

    @Override
    public void init(ConfigContext configContext) {
        // 请求器初始化
        String httpClientClassName = configContext.getHttpClientClassName();
        IHttpClinet httpClinet = null;
        if (StringUtils.isNotBlank(httpClientClassName)) {
            httpClinet = (IHttpClinet) ClassUtil.newInstance(httpClientClassName);
        } else {
            httpClinet = new DefeatHttpClient();
        }
        ClassUtil.setStaticField(BaseService.class, "iHttpClinet", httpClinet);

        log.info("微信sdk初始化开始，如果您使用的是分布式支持模式，如果等待时间过长，没有继续输出信息，那么请检查zookeeper服务器是否启动。");
        ClassUtil.setStaticField(CommonService.class, "iAccessTokenService", initIAccessTokenService(configContext));
    }
    /**
     * 用于初始华 AccessTokenService
     */
    private IAccessTokenService initIAccessTokenService(ConfigContext configContext) {
        IAccessTokenService iAccessTokenService;
        boolean mode = configContext.isDistributedMode();
        if (!mode) {
            iAccessTokenService = AccessTokenSingleService.getInstance();
        } else {
            ConfigContext.DistributedConfig dirstributedConfig = configContext.getDirstributedConfig();
            int sessionTimeout = dirstributedConfig.getSessionTimeout();
            String zkServiceList = dirstributedConfig.getZkServiceList();
            HashMap<String, PublicAccount> publicAccountMap = dirstributedConfig.getPublicAccountMap();
            iAccessTokenService = AccessTokenDistributedService.getInstance(sessionTimeout, zkServiceList, publicAccountMap);
        }
        return iAccessTokenService;
    }
    /** 该类初始化操作是否准备完成 */
    public boolean isInitReady() {
        return initReady;
    }
    @Override
    public ConfigContext getConfigContext() {
        return configContext;
    }

    public void setId(String id) {
        configContext.setId(id);
    }
}
